"""Provide helpers that cache URL requests for a while."""
import functools
from http import HTTPStatus
import time
import typing

from cki_lib.logger import get_logger
from cki_lib.session import get_session
from datawarehouse import objects
import requests.exceptions

from . import settings

LOGGER = get_logger(__name__)
SESSION = get_session(__name__)


def get_cache_ttl(duration: float = 300) -> int:
    """Generate a hash to invalidate the cached call signature."""
    return round(time.time() / duration)


@functools.lru_cache(maxsize=1000)  # big number but not too big
def get_checkout(ttl_hash: int, checkout_id: str) -> objects.KCIDBCheckout:
    """Retrieve and cache the checkout object."""
    del ttl_hash  # Not used, just a param to invalidate lru_cache
    return settings.DW_CLIENT.kcidb.checkouts.get(checkout_id)


@functools.lru_cache(maxsize=1000)  # big number but not too big
def get_build(ttl_hash: int, build_id: str) -> objects.KCIDBBuild:
    """Retrieve and cache the build object."""
    del ttl_hash  # Not used, just a param to invalidate lru_cache
    return settings.DW_CLIENT.kcidb.builds.get(build_id)


@functools.lru_cache(maxsize=1)
def get_issueregexes(ttl_hash: int, issueregex_ids: tuple[int]) -> list[objects.IssueRegex]:
    """Download and compile regexes from Datawarehouse."""
    del ttl_hash  # Not used, just a param to invalidate lru_cache
    LOGGER.debug('Downloading lookups. issueregex_ids: %s', issueregex_ids)
    if issueregex_ids:
        return [r for issueregex_id in issueregex_ids if (r := _download_regex(issueregex_id))]
    return typing.cast(list[objects.IssueRegex], settings.DW_CLIENT.issue_regex.list(limit=200))


def _download_regex(issueregex_id: int) -> typing.Optional[objects.IssueRegex]:
    """Try to download a regex, and returns None for a missing one."""
    try:
        return settings.DW_CLIENT.issue_regex.get(id=issueregex_id)
    except requests.exceptions.HTTPError as exception:
        # the regex might have been deleted in the meanwhile
        if exception.response.status_code == HTTPStatus.NOT_FOUND:
            LOGGER.warning('Unable to find regex %s, assuming it is deleted', issueregex_id)
            return None
        raise
